package com.hilihili.job;

import cn.hutool.json.JSONUtil;
import com.hilihili.domain.vo.ViewCounts;
import com.hilihili.service.IVideoService;
import com.hilihili.constant.RedisVideoConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * redis 相关数据更新定时任务类
 *
 * @author machi
 * @date 2023/12/06
 */
@Component
public class RedisUpdateSchedule {
    @Autowired
    IVideoService videoService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;


    /**
     * 每5秒同步一次redis和数据库的视频播放量数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0/5 * * * * ? ")
    public void updateViewsNumber() {
        //获取所有以hilihili:video:viewsCounts:开头的key
        Set<String> keys = stringRedisTemplate.keys(RedisVideoConstant.VIEW_COUNTS.concat("*"));
        if (keys == null || keys.isEmpty()) {
            return;
        }
        List<String> strings = stringRedisTemplate.opsForValue().multiGet(keys);
        if (strings == null || strings.isEmpty()) {
            return;
        }
        List<ViewCounts> viewCounts = JSONUtil.toList(strings.toString(), ViewCounts.class);
        videoService.batchUpdateVideo(viewCounts);

    }


    /**
     *
     * 每一分钟扫描一次redis中 hilihili:video:non-addable:的key 防止占用空间
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void removeNotAddableFromRedis() {
        //获取所有以 hilihili:video:non-addable: 的key
        Set<String> keys = stringRedisTemplate.keys(RedisVideoConstant.VIEWS_NUMBER_NOT_ADDABLE.concat("*"));
        if (keys == null || keys.isEmpty()) {
            return;
        }
        ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
        keys.forEach(key -> opsForZSet.removeRangeByScore(key, 0, System.currentTimeMillis()));
    }

}
